#include "StdAfx.h"

#include <stdio.h>

#include "EphemEPM.h"
#include "CustomException.h"
#include "EphemWrapper.h"
#include "SimpleFile.h"
#include "AsteroidOrbitParam.h"
#include "Trajectory.h"
#include "Approach.h"
#include "RadaParamInterface.h"
#include "DEEphem.h"

void PrintDate(double dDate)
{
	int year;
	int month;
	int date;
	double daypart;
	CEphemWrapper::DateFromJD(dDate, year, month, date, daypart);
	daypart *= 24.0;
	int nhour = int(daypart);
	daypart = (daypart - nhour) * 60.0;
	int nminut = int(daypart);
	daypart = (daypart - nminut) * 60.0;
	
	printf("date: %d/%2d/%2d time=%2d:%2d:%5.2lf  (jd=%15.7lf)\n", year, month, date, nhour, nminut, daypart, dDate);
}

CEphemWrapper::Ptr GetEphem(LPCTSTR stzEphemParamName)
{
	int nEphemNum = 0;
	TCHAR stzDataPath[MAX_PATH];
	{
		CSimpleFile fileEfemParam(stzEphemParamName, "r");
		fscanf(fileEfemParam, _T("%d"), &nEphemNum);
		fscanf(fileEfemParam, _T("%s"), stzDataPath);
	}
	LPTSTR stzFileName = NULL;
	switch(nEphemNum)
	{
		case 1:	stzFileName =_T("EPM2008"); 	break;
		case 2:	stzFileName =_T("de403.dos"); 	break;
		case 3:	stzFileName =_T("de405.dos"); 	break;
		case 4:	stzFileName =_T("de414.dos"); 	break;
		case 5:	stzFileName =_T("de421.dos"); 	break;
		case 6:	stzFileName =_T("de423.dos"); 	break;
		default: throw CCustomException("Unknown ephem num %d", nEphemNum);
	}
	strcat(stzDataPath, stzFileName);

	CEphemWrapper::Ptr pRes(new CEphemWrapper(stzDataPath, (nEphemNum==1)? CEphemWrapper::eEPM: CEphemWrapper::eDE));

	return pRes;
}

CAsteroidOrbitParam::Ptr GetAsteroidParam(LPCTSTR stzParamFileName)
{
	CAsteroidOrbitParam::Ptr pAsteroidParam(new CAsteroidOrbitParam(0.0));

	double	dStartTime;
	double	dEndTime;
	SBody	bodyRefPos;

	int wasRead = 0;
	CSimpleFile InFile(stzParamFileName, _T("r"));
	wasRead += fscanf(InFile, _T("%le"), &dStartTime);
	for(int i = 0; i< sizeof(bodyRefPos.x)/sizeof(bodyRefPos.x[0]); i++)
		wasRead += fscanf(InFile, _T("%le"), bodyRefPos.x + i);

	for(int i = 0; i< sizeof(bodyRefPos.v)/sizeof(bodyRefPos.v[0]); i++)
		wasRead += fscanf(InFile, _T("%le"), bodyRefPos.v + i);
	wasRead += fscanf(InFile, _T("%le"), &dEndTime);
	if(wasRead != 8)
		throw CCustomException(_T("error reading input param %d read must be 8"), wasRead);

	printf(" input start parametrs:\n\n ");
	for(int i = 0; i<sizeof(bodyRefPos.x)/sizeof(bodyRefPos.x[0]); ++i)
		printf("%25.16E ", bodyRefPos.x[i]);
	printf("\n ");
	for(int i = 0; i<sizeof(bodyRefPos.v)/sizeof(bodyRefPos.v[0]); ++i)
		printf("%25.16E ", bodyRefPos.v[i]);
	printf("\n");

	*pAsteroidParam = bodyRefPos;
	pAsteroidParam->m_dStart = dStartTime;
	pAsteroidParam->m_dEnd = dEndTime;

	return pAsteroidParam;
}

int FortEqv()
{
	try
	{
		CEphemWrapper::Ptr pEphemeride = GetEphem(_T("ephem.ini"));
		CAsteroidOrbitParam::Ptr pAsteroidParam = GetAsteroidParam(_T("param.in.txt"));

		printf(" start time:\n");
		PrintDate(pAsteroidParam->m_dStart);
		
		SBody StartBoby = *pAsteroidParam;
		SBody body = StartBoby;

		CTrajectory trajectory(pEphemeride, pAsteroidParam, 10.0);

		ListPtrApproachs appListTo = trajectory.Move(pAsteroidParam->m_dStart, pAsteroidParam->m_dEnd, body, NULL);
		SBody bodyMidle = body;
		ListPtrApproachs appListFrom = trajectory.Move(pAsteroidParam->m_dEnd, pAsteroidParam->m_dStart,  body, NULL);
		
		for(ListPtrApproachs::const_iterator it = appListTo.begin(); it != appListTo.end(); ++it)
			(*it)->Print();

		{
			printf("end time:\n");
			PrintDate(pAsteroidParam->m_dEnd);
			printf("%lf\n", pAsteroidParam->m_dEnd);
			for(int i = 0; i<sizeof(bodyMidle.x)/sizeof(bodyMidle.x[0]); ++i)
				printf("%25.16E ", bodyMidle.x[i]);
			printf("\n");
			for(int i = 0; i<sizeof(bodyMidle.v)/sizeof(bodyMidle.v[0]); ++i)
				printf("%25.16E ", bodyMidle.v[i]);
			printf("\n");
		}

		for(ListPtrApproachs::const_iterator it = appListFrom.begin(); it != appListFrom.end(); ++it)
			(*it)->Print();

		{
			printf("end time:\n");
			PrintDate(pAsteroidParam->m_dEnd);
			printf("%lf\n", pAsteroidParam->m_dEnd);
			for(int i = 0; i<sizeof(body.x)/sizeof(body.x[0]); ++i)
				printf("%25.16E ", body.x[i]);
			printf("\n");
			for(int i = 0; i<sizeof(body.v)/sizeof(body.v[0]); ++i)
				printf("%25.16E ", body.v[i]);
			printf("\n");
		}
		{
			printf("\n ================== difference: ================== \n");
			for(int i = 0; i<sizeof(body.x)/sizeof(body.x[0]); ++i)
				printf("%25.16E ", 0.5 *(body.x[i] - StartBoby.x[i])/(body.x[i] + StartBoby.x[i]));
			printf("\n");
			for(int i = 0; i<sizeof(body.v)/sizeof(body.v[0]); ++i)
				printf("%25.16E ", 0.5 *(body.v[i] - StartBoby.v[i])/(body.v[i] + StartBoby.v[i]));
			printf("\n");
		}
	}
	catch(const CCustomException &e)
	{
		printf(_T("%s\n"), e.GetErrorStr());
	}
	catch(...)
	{
		printf(_T("unknown error\n"));
	}
	//printf("Press any key...");
	//getc(stdin);
	return 0;
}


int main()
{
	FortEqv();
	return 0;
}

